package com.fanghaoran.notes.controller;

import com.alibaba.fastjson.JSON;
import com.fanghaoran.notes.bean.MyResult;
import com.fanghaoran.notes.entity.User;
import com.fanghaoran.notes.service.OrderService;
import com.fanghaoran.notes.service.UserService;
import com.fanghaoran.notes.service.impl.OrderServiceImpl;
import com.fanghaoran.notes.service.impl.UserServiceImpl;
import com.fanghaoran.notes.util.*;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.time.LocalDateTime;

/**
 * @Author: win11
 * @Date: 2023/04/13/14:03
 * @Description:
 */
@WebServlet("/user")
@MultipartConfig(
        //上传文件的大小
        fileSizeThreshold = 1024 * 1024 * 10, // 10 MB
        maxFileSize = 1024 * 1024 * 50, // 50 MB
        maxRequestSize = 1024 * 1024 * 100 // 100 MB
)
public class UserController extends BaseServlet {

    /**
     * service对象
     */
    UserService userService = new UserServiceImpl();
    OrderService orderService = new OrderServiceImpl();


    /**
     * 登录
     *
     * @param request  浏览器端发送的请求数据
     * @param response 响应登录结果
     * @throws Exception 异常
     */
    public void login(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String autoLogin = request.getParameter("autoLogin");
        //System.out.println("自动登录选项:"+autoLogin);
        User userInput = new User();
        userInput.setUsername(username);
        userInput.setPassword(password);
        MyResult loginResult = userService.login(userInput);
        if (loginResult.getCode().equals(Constants.EMPTY)) {
            //json格式传输
            response.getWriter().println(JSON.toJSONString(new MyResult(Constants.FAIL, null)));
        } else {
            //查询到的用户数据
            User user = (User) loginResult.getData();
            User userToSession = new User();
            userToSession.setUId(user.getUId());
            userToSession.setUsername(username);
            userToSession.setIsMerchant(user.getIsMerchant());

            //创建session并将用户名保存到session
            request.getSession().setAttribute(Constants.LOGIN_SESSION_PARAM, userToSession);
            //判断是否自动登录
            Cookie cookie;
            if (!("1".equals(autoLogin))) {
                //没有勾选自动登录
                //不需要存储本地cookie
                cookie = new Cookie(Constants.AUTO_USER_PARAM, "");
                //设置所有路径都可以访问
                cookie.setPath("/");
                cookie.setMaxAge(0);
            } else {
                //选了 自动登录
                //将用户名存入cookie 并设定时间
                cookie = new Cookie(Constants.AUTO_USER_PARAM, user.getUId().toString());
                cookie.setPath("/");
                //设置cookie存储时间->一周
                cookie.setMaxAge(7 * 24 * 60 * 60);

            }
            response.addCookie(cookie);
            response.getWriter().println(JSON.toJSONString(new MyResult(Constants.SUCCESS, user.getIsMerchant())));
        }
    }

    /**
     * 注销
     *
     * @param request  请求
     * @param response 响应
     * @throws IOException 异常
     */
    public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //1.清空session
        request.getSession().removeAttribute(Constants.LOGIN_SESSION_PARAM);
        //2.注销cookie
        Cookie cookie = new Cookie(Constants.AUTO_USER_PARAM, "");
        cookie.setPath("/");
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        //3.转发到登录页面
        response.sendRedirect("login.html");
    }

    /**
     * 注册
     *
     * @param request  请求
     * @param response 响应
     * @throws Exception 异常
     */
    public void register(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String email = request.getParameter("email");
        String isMerchant = request.getParameter("isMerchant");
        LocalDateTime registerTime = LocalDateTime.now();
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setEmail(email);
        user.setIsMerchant(Integer.parseInt(isMerchant));
        user.setRegisterTime(registerTime);
        //交给业务层并返回的结果
        Integer code = userService.register(user).getCode();
        if (code.equals(Constants.FAIL)) {
            response.getWriter().println(JSON.toJSONString(new MyResult(Constants.FAIL, "因系统原因,注册失败")));
        } else if (code.equals(Constants.NONEMPTY)) {
            response.getWriter().println(JSON.toJSONString(new MyResult(Constants.NONEMPTY, "用户/邮箱已存在")));
        } else {
            response.getWriter().println(JSON.toJSONString(new MyResult(Constants.SUCCESS, "注册成功")));
        }
    }

    /**
     * 获取验证码
     *
     * @param request  前端发送获取验证码的请求
     * @param response 返回给前端的验证码
     * @throws IOException 异常
     */
    public void getCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.getWriter().println(JSON.toJSONString(CodeUtil.getCode()));
    }

    /**
     * 获取验证码并发送给指定邮箱
     *
     * @param request  前端的请求
     * @param response 响应数据
     */
    public void sendCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //要发送给的邮箱
        String email = request.getParameter("email");
        User user = new User();
        user.setEmail(email);
        //传入数据给业务层处理并返回结果
        MyResult result = userService.sendCode(user);
        if (result.getCode().equals(Constants.EMPTY)) {
            response.getWriter().println(JSON.toJSONString(new MyResult(Constants.FAIL, "邮箱未注册")));
        } else {
            response.getWriter().println(JSON.toJSONString(new MyResult(Constants.SUCCESS, result.getData())));
        }
    }

    /**
     * 修改密码
     *
     * @param request  请求
     * @param response 响应
     * @throws SQLException 异常
     * @throws IOException  异常
     */
    public void modifyPwd(HttpServletRequest request, HttpServletResponse response) throws SQLException, IOException {
        String email = request.getParameter("email");
        String newPwd = request.getParameter("newPwd");
        User user = new User();
        user.setEmail(email);
        user.setPassword(newPwd);
        //传入数据给业务层处理并返回结果
        Integer code = userService.modifyPwd(user).getCode();
        if (code.equals(Constants.FAIL)) {
            response.getWriter().println(JSON.toJSONString(new MyResult(Constants.FAIL, "因系统原因,修改密码失败")));
        } else {
            response.getWriter().println(JSON.toJSONString(new MyResult(Constants.SUCCESS, "修改密码成功")));
        }
    }

    /**
     * 获取用户信息
     *
     * @param request  请求
     * @param response 响应
     * @throws Exception 异常
     */
    public void getUserInfo(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //从session或者cookie中获取用户名 看看用户是否登录
        User user = (User) request.getSession().getAttribute(Constants.LOGIN_SESSION_PARAM);
        //业务层查询
        response.getWriter().println(JSON.toJSONString(userService.getUserInfoByUid(user.getUId())));
    }

    /**
     * 上传头像
     * @param request 请求
     * @param response 响应
     * @throws Exception 异常
     */
    public void uploadPhoto(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 获取请求的数据类型
        String contentType = request.getContentType();
        // 确认请求数据类型为 multipart/form-data 类型
        if (contentType != null && contentType.startsWith(Constants.IS_FILE)) {
            // 获取文件上传的 input 元素名称为 "file" 的 Part 对象
            Part filePart = request.getPart("file");
            System.out.println(filePart);
            // 确认获取到了上传的文件内容
            if (filePart != null) {
                // 调用 getSubmittedFileName() 方法获取上传的文件名
                String fileName = filePart.getSubmittedFileName();
                // 获取保存文件的目录
                String savePath = Constants.DEST;
                // 更改保存的图像格式
                BufferedImage img = ImageIO.read(filePart.getInputStream());
                ImageIO.write(img, Constants.IMAGE_FORMAT, new File(savePath, fileName));
                //获取用户名
                User user = (User) request.getSession().getAttribute(Constants.LOGIN_SESSION_PARAM);
                Integer uId = user.getUId();
                //调用业务层方法修改数据库存储
                userService.updatePhoto(uId, fileName);

            }
        } else {
            System.out.println("格式错误");
        }
    }

    /**
     * 修改余额(支付时)
     * @param request 请求
     * @param response 响应
     * @throws Exception 异常
     */
    public void modifyBalance(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //获取前端总花费参数以及订单号参数
        String count = request.getParameter("totalCount");
        BigDecimal totalCount = new BigDecimal(count);
        String oId = request.getParameter("oId");
        //获取当前用户
        User user = (User) request.getSession().getAttribute(Constants.LOGIN_SESSION_PARAM);
        //获取用户id
        Integer uId = user.getUId();
        //交给业务层去处理
        response.getWriter().println(JSON.toJSONString(userService.modifyBalance(uId, oId, totalCount)));
    }

    /**
     * 修改余额(退款时)
     * @param request 请求
     * @param response 响应
     * @throws Exception 异常
     */
    public void modifyBalanceOfRefund(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //获取退款金额以及退款者id
        String count = request.getParameter("count");
        BigDecimal totalCount = new BigDecimal(count);
        String buyerId = request.getParameter("buyerId");
        //获取当前商家
        User user = (User) request.getSession().getAttribute(Constants.LOGIN_SESSION_PARAM);
        //获取商家id
        Integer sellerId = user.getUId();
        //业务层
        response.getWriter().println(JSON.toJSONString(userService.modifyBalanceOfRefund(Integer.parseInt(buyerId), sellerId, totalCount)));
    }
}
